昨天成功的讓 Prometheus 收集了一些指標,那麼今天就來設定警報吧。要做警報的話,在 Prometheus 裡面是透過 config 的 rules 欄位。目前有兩種 rule,一種是 recording rules,用來計算一些常用的指標並把它存下來,另一種是 alerting rules,顧名思義就是用來設定警報規則的。
那們首先第一個警報,我們就來做當服務掛掉的時候會發出通知吧,首先在 prometheus.yml 的隔壁創建一個 alert.yml,寫入以下內容(取自官方文件):
groups:
  - name: example
    rules:
      # Alert for any instance that is unreachable for >5 minutes.
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: page
        annotations:
          summary: "Instance {{ $labels.instance }} down"
          description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
簡單介紹一下裡面的結構,它的根一定會是 groups,內容為 rule_group 組成的陣列,每個 rule_group 須帶有一個不重複的 name 作為識別,並且定義 rules 陣列,每個 rule 物件的 alert 欄位表示它的名字,expr 為檢查的表達式(使用 PromQL 語法),以上面的例子來說 up == 0 表示有任何一個 target 抓不到的情形。for 表示這個條件要持續多久,才會形成一個警報。labels 跟 annotation 都是用來在警報上面加上額外資訊的,不過他們的用途稍有不同,在後面設定 Alertmanager 會詳細介紹。
訂好 alerting rules 之後,我們還需要讓 Prometheus 可以讀到它,所以在 prometheus.yml 裡面加上 rule_files:
# 加上這個!
rule_files:
  - alert.yml
scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: node
    static_configs:
      - targets: ["node-exporter:9100"]
  - job_name: caddy
    static_configs:
      - targets: ["caddy:3939"]
然後重開服務,打開 http://localhost:9090/rules,應該會看到以下畫面,那我們就成功載入 alerting rules 了。

雖然替 Prometheus 設定好 alerting rules 了,然而它本身其實並沒有處理發送警報給我們的部分,而是透過 Alertmanager 來達成,所以我們還需要在 docker compose 裡面,新增一個 Alertmanager 的服務,在 docker-compose.yml 的 services 裡面新增 alertmanager 的定義:
alertmanager:
  image: prom/alertmanager:v0.23.0
  restart: unless-stopped
  volumes:
    - ./alertmanager:/etc/alertmanager
  command:
    - '--config.file=/etc/alertmanager/config.yml'
    - '--storage.path=/alertmanager'
然後我們還需要撰寫 Alertmanager 的設定檔,建立 alertmanager/config.yml,並且寫入下面內容:
route:
  receiver: "gmail-notifications"
receivers:
  - name: "gmail-notifications"
    email_configs:
      - to: <your-gmail>
        from: <your-gmail>
        smarthost: smtp.gmail.com:587
        auth_username: <your-gmail>
        auth_identity: <your-gmail>
        auth_password: <google app password>
        send_resolved: true
這邊需要申請一個 google 的應用程式密碼才能讓 Alertmanager 寄信到 gmail 信箱,設定的方式可以參考這邊。成功取得密碼之後把它填上去上面的 password 欄位,並且把其他 <your-gmail> 的部分換成自己的 gmail 帳號即可。
最後一步,你還需要告訴 Prometheus 要去哪邊找 Alertmanager,所以還要再修改一次 prometheus.yml,加入 alerting 這項設定:
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - "alertmanager:9093"
修改完成後,重開服務,順便把 NOJ 關掉,等個幾分鐘再打開信箱,就會看到 Alertmanager 送來的郵件了:

如果不確定警告是否有從 Prometheus 發出去的,也可以使用 ALERTS 這個表達式來查詢:

今天成功的發出警告了,感覺又讓這個專案成長了一點,並且關於 Prometheus 的架設也算是到了尾聲,之後就是根據服務需求來設置各種警報的規則,關於這點我想官方文件的 best practice 應該值得參考,有興趣的讀者可以看看。